package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import main.H;

/**
 *
 * @author benjamin
 */
public class ClientHandler implements Runnable {

    private String name;
    private Boolean isActive;
    private Server server;
    private Socket client;
    private PrintWriter clientOut = null;
    private BufferedReader clientIn = null;

    public String getName() {
        return name;
    }

    public Boolean isActive() {
        return isActive;
    }

    public void kill() {
        isActive = false;
    }

    public ClientHandler(Server _server, Socket _client) {
        isActive = true;
        server = _server;
        client = _client;
        try {
            clientIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
            clientOut = new PrintWriter(client.getOutputStream(), true);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        //clientOut.println(data);
    }

    @Override
    public void run() {
        /*
         * //JOptionPane.showMessageDialog(null, clientIn.readLine()); name =
         * getStrFromCmd(clientIn.readLine(), "nick=");
         * //server.handleClientMessage(new Message("Client " +
         * client.toString() + " connected!")); server.handleClient("Client " +
         * name + " connected!");
         */
        while (isActive) {
            try {
                //Receive data from the client
                String data = clientIn.readLine();
                if (data != null) {
                    handleInput(data);
                }
            } catch (IOException ex) {
            }
        }
        try {
            server.broadcastDataString("Client " + name + " disconnected!");
            clientIn.close();
            clientOut.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void handleInput(String data) {
        //JOptionPane.showMessageDialog(null, clientIn.readLine());
        String cmdStr = getCmdFromInput(data);
        H.PL(cmdStr);
        Commands cmd = parseCommand(cmdStr);
        String dataAfterCmd = getStrFromCmd(data, "/" + cmdStr + " ");
        //H.PL("Input: " + data);
        //H.PL("Command: " + cmd + ". String: " + dataAfterCmd);
        if (cmd != null) {
            switch (cmd) {
                case NICK:
                    changeNick(dataAfterCmd);
                    break;
                case HELP:
                    printServerCommands();
                    break;
                default:
                    printServerCommands();
                    break;
            }
        } else {
            sendMessage(data);
        }
    }
    
    private void sendMessage(String data) {
        data = "[" + getName() + "]: " + data;
        server.broadcastDataString(data);
    }
    
    private void changeNick(String newNick) {
        if(newNick != null) {
            name = newNick;
            server.broadcastDataString("Client " + name + " connected!");
            server.addMessage("Client " + name + " connected!");
        } else {
            server.broadcastDataString("Usage: '/nick [new nick here]'.");
        }
    }
    private void printServerCommands() {
        server.broadcastDataString("Valid commands: " + Commands.getValues());
        server.broadcastDataString("Example usage of a command for changing nick: '/nick [new nick here]'");
    }

    private Commands parseCommand(String cmd) {
        try {
            return Commands.valueOf(Commands.class, cmd.toUpperCase());
        } catch (Exception ex) {
            return null;
        }
    }

    private String getCmdFromInput(String str) {
        String[] strSplit = str.split(" ");
        String cmdId = "/";
        if (strSplit[0].startsWith(cmdId)) {
            return strSplit[0].replace(cmdId, "");
        }
        return null;
    }

    private String getStrFromCmd(String str, String cmdStr) {
        if (str.startsWith(cmdStr)) {
            return str.replace(cmdStr, "").trim();
        }
        return null;
    }

    /**
     * Send data to the client
     *
     * @param msg Message to send
     */
    public void sendData(String msg) {
        clientOut.println(msg);
    }
}
